package com.unieagle.exam.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.JsonRequest;
import com.android.volley.toolbox.Volley;
import com.unieagle.exam.R;
import com.unieagle.exam.account.AccountManager;
import com.unieagle.exam.db.DatabaseContext;
import com.unieagle.exam.db.ExamDBHelper;
import com.unieagle.exam.model.Question;
import com.unieagle.exam.model.Subject;
import com.unieagle.exam.utils.DateUtils;
import com.unieagle.exam.utils.HttpUtils;
import com.unieagle.exam.utils.NetworkUtils;
import com.unieagle.exam.utils.SharedPreferenceUtils;

public class UpdateActivity extends BaseActivity implements View.OnClickListener{
	
	private static final String TYPE_S = "subjects";
    
    private static final String TYPE_Q = "questions";
	
    private ImageButton mIbBack;
    
    private TextView mTvHint, mTvProgress;
    
    private ProgressBar mPbProgress;
    
    private String current_type;
    
    private int total_subject_update_page_size = 1;
    
    private int total_question_update_page_size = 1;
    
    private boolean subjectHasUpdate, questionHasUpdate;
    
    private List<Subject> mSubjectList;
    
    private List<Question> mQuestionList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        immersedStyle();
        setContentView(R.layout.update_activity_layout);
        mIbBack = (ImageButton) findViewById(R.id.back);
        mTvHint = (TextView) findViewById(R.id.update_hint);
        mTvProgress = (TextView) findViewById(R.id.progress);
        mPbProgress = (ProgressBar) findViewById(R.id.progressbar);
        mIbBack.setOnClickListener(this);
        mSubjectList = new ArrayList<Subject>();
        mQuestionList = new ArrayList<Question>();
        update(TYPE_S, 1);
    }
    
    private void update(String type, int page) {
    	current_type = type;
		if(!NetworkUtils.isNetworkAvailable(this)) {
			mTvHint.setText(R.string.no_network);
			return;
		}
		RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
		JSONObject jsonObject = new JSONObject();
		try {
			jsonObject.put("access_token", AccountManager.getInstance().getAccessToken());
			jsonObject.put("last_updated_at", SharedPreferenceUtils.getLastUpdatedTime(this));
			jsonObject.put("update_type", type);
			jsonObject.put("page", page);
			
		} catch(JSONException e) {
			e.printStackTrace();
			return;
		}
		JsonRequest<JSONObject> jsonRequest = new JsonObjectRequest(Method.POST, 
				HttpUtils.getUpdateSubjectAndQuestionUrl(), jsonObject,
		    new Response.Listener<JSONObject>() {
		        @Override
		        public void onResponse(JSONObject response) {
		        	if(current_type == TYPE_S) {
		        		mSubjectList.clear();
		        		total_subject_update_page_size = response.optJSONObject("summary").optInt("total_pages");
		        		int current_page = response.optJSONObject("summary").optInt("current_page");
		        		JSONArray list = response.optJSONObject("data").optJSONArray("subjects");
		        		if(list.length() == 0) {
		        			subjectHasUpdate = false;
		        			update(TYPE_Q, 1);
		        		} else {
		        			subjectHasUpdate = true;
		        			findViewById(R.id.progress_container).setVisibility(View.VISIBLE);
			        		for(int i = 0; i < list.length(); i++) {
			        			mSubjectList.add(Subject.parse(list.optJSONObject(i)));
			        		}
			        		mPbProgress.setProgress(10);
			        		mTvProgress.setText("10%");
			        		new UpdateTask().execute(current_page);
		        		}
		        	} else {
		        		mQuestionList.clear();
		        		total_question_update_page_size = response.optJSONObject("summary").optInt("total_pages");
		        		int current_page = response.optJSONObject("summary").optInt("current_page");
		        		JSONArray list = response.optJSONObject("data").optJSONArray("questions");
		        		if(list.length() == 0) {
			        		questionHasUpdate = false;
			        		if(subjectHasUpdate) {
			        			updateUpdateTime();
								mTvHint.setText(R.string.update_complete);
			        		} else {
			        			mTvHint.setText(R.string.no_update);
			        		}
		        		} else {
		        			questionHasUpdate = true;
		        			findViewById(R.id.progress_container).setVisibility(View.VISIBLE);
		        			for(int i = 0; i < list.length(); i++) {
			        			mQuestionList.add(Question.parse(list.optJSONObject(i)));
			        		}
		        			mPbProgress.setProgress(10 + 90 * current_page / total_question_update_page_size);
		        			mTvProgress.setText((10 + 90 * current_page / total_question_update_page_size) + "%");
			        		new UpdateTask().execute(current_page);
		        		}
		        	}
		        }
		    }, new Response.ErrorListener() {
		        @Override
		        public void onErrorResponse(VolleyError error) {
		        	
		    }
		    }) {
			    @Override
			    public Map<String, String> getHeaders() {
			        HashMap<String, String> headers = new HashMap<String, String>();
			        headers.put("Accept", "application/json");
			        headers.put("Content-Type", "application/json; charset=UTF-8");       
			        return headers;
			    }
		};
		requestQueue.add(jsonRequest);
	}
    
    class UpdateTask extends AsyncTask<Integer, Void, Boolean> {
    	
    	private int page;
    	
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mTvHint.setText(R.string.update_question_bank);
		}

		@Override
		protected Boolean doInBackground(Integer... arg0) {
			page = arg0[0];
			ExamDBHelper helper = new ExamDBHelper(new DatabaseContext(UpdateActivity.this));
			if(current_type.equals(TYPE_S)) {
				return helper.updateSubjects(mSubjectList);
			} else {
				return helper.updateQuestionsAndAnswers(mQuestionList);
			}
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			page++;
			if(result) {
				if(current_type.equals(TYPE_S)) {
					if(page <= total_subject_update_page_size) {
						update(TYPE_S, page);
					} else {
						update(TYPE_Q, 1);
					}
				} else {
					if(page <= total_question_update_page_size) {
						update(TYPE_Q, page);
					} else {
						updateUpdateTime();
						mTvHint.setText(R.string.update_complete);
					}
				}
			}
		}
    	
    }
    
    private void updateUpdateTime() {
    	String time = DateUtils.getDate(System.currentTimeMillis()) + " UTC";
    	SharedPreferenceUtils.setLastUpdatedTime(this, time);
    	findViewById(R.id.progress_container).setVisibility(View.GONE);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        switch (id){
            case R.id.back:
                finish();
                break;
        }
    }
}
